package com.teamin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mysql.cj.core.util.StringUtils;
import com.teamin.config.ErrorCode;
import com.teamin.entity.WxGroupEntity;
import com.teamin.entity.WxUserEntity;
import com.teamin.mapper.WxUserMapper;
import com.teamin.service.WxService;
import com.teamin.utils.WXAESUtils;
import com.teamin.utils.WxPKCS7Encoder;
import com.teamin.web.exception.GlobalErrorInfoException;
import com.teamin.web.model.ErrorInfo;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.util.Base64;

@Component
public class WxServiceImpl implements WxService {
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	// 微信appid
	@Value("${wx.appid}")
	String wx_appid;
	// 微信密匙
	@Value("${wx.secret}")
	String wx_secret;
	
	@Autowired
	WxUserMapper wxUserMapper;
	
	/**
	 *获取微信用户
	 */
	public WxUserEntity getWxUserEntity(String code, String encryptedData, String iv) throws GlobalErrorInfoException {
		try {
			JSONObject jsonObject = getSmallWX(code, wx_appid, wx_secret);
			// logger.info("获取微信用户的基本信息 : " + jsonObject.toJSONString());
			String session_key = jsonObject.getString("session_key");

			JSONObject decodeEncrData = decodeEncrData(encryptedData, iv, session_key);

			// logger.info("获取微信解密信息 : " + decodeEncrData.toJSONString());
			WxUserEntity wxUserEntity = JSON.parseObject(decodeEncrData.toString(), WxUserEntity.class);
			wxUserEntity.setSessionKey(session_key);

			if(jsonObject.containsKey("unionid") && !StringUtils.isNullOrEmpty(jsonObject.getString("unionid"))) {
				wxUserEntity.setUnionId(jsonObject.getString("unionid"));
			}else {
				wxUserEntity.setUnionId(decodeEncrData.getString("unionId"));
			}

			if(jsonObject.containsKey("openid") && !StringUtils.isNullOrEmpty(jsonObject.getString("openid"))) {
				wxUserEntity.setOpenId(jsonObject.getString("openid"));
			}else {
				wxUserEntity.setOpenId(decodeEncrData.getString("openId"));
			}
			return wxUserEntity;
		} catch (Exception e) {
			logger.warn(e.getMessage(), e);
			throw new GlobalErrorInfoException(new ErrorInfo(HttpStatus.BAD_REQUEST, ErrorCode.GET_WXUSER_FAIL));
		}

	}

	/**
	 *获取微信群
	 */
	@Override
	public String getGroupId(String encryptedData, String iv,Long userId) throws GlobalErrorInfoException {
		try {
			String session_key = null;
			WxUserEntity userEntity = wxUserMapper.selectWxUserEntityByUser(userId);
				session_key = userEntity.getSessionKey();
			logger.info("session_key="+session_key);
			JSONObject decodeEncrData = decodeEncrData(encryptedData, iv, session_key);
			return decodeEncrData.getString("openGId");
		} catch (Exception e) {
			logger.warn(e.getMessage(), e);
		}
		return null ;
	}

	/**
	 *获取微信群
	 */
	@Override
	public WxGroupEntity decrypedWxGroupEntity(String code, String encryptedData, String iv,Long userId) {
		logger.info("decrypedWxGroupEntity="+code+" "+encryptedData+" "+iv+" "+userId);
		try {			
			String session_key = null;
			if (!StringUtils.isNullOrEmpty(code)) {
				JSONObject jsonObject = getSmallWX(code, wx_appid, wx_secret);
			    session_key = jsonObject.getString("session_key");
			} else {
				WxUserEntity userEntity = wxUserMapper.selectWxUserEntityByUser(userId);
				session_key = userEntity.getSessionKey();
				logger.info("session_key="+userEntity.toString()+userEntity);
			}
			logger.info("session_key="+session_key);
			JSONObject decodeEncrData = decodeEncrData(encryptedData, iv, session_key);
			WxGroupEntity wxGroupEntity = new WxGroupEntity();
			wxGroupEntity.setGroupId(decodeEncrData.getString("openGId"));
			wxGroupEntity.setGroupName("");
			return wxGroupEntity;
		} catch (Exception e) {
			logger.warn(e.getMessage(), e);
		}
		return null ;
	}
	
	/**
	 * 获取用户信息
	 * 
	 * @param jsCode
	 * @param appid
	 * @param secret
	 * @return
	 * @throws IOException
	 */
	public JSONObject getSmallWX(String jsCode, String appid, String secret) throws Exception {
		OkHttpClient okHttpClient = new OkHttpClient();
		Request request = new Request.Builder().url("https://api.weixin.qq.com/sns/jscode2session?appid=" + appid
				+ "&secret=" + secret + "&js_code=" + jsCode + "&grant_type=authorization_code").build();
		Call call = okHttpClient.newCall(request);
		Response response = call.execute();
		return JSON.parseObject(response.body().string());
	}
	/**
	 * 解密微信数据
	 * 
	 * @param encrData
	 * @param v1
	 * @param sessionKey
	 * @return
	 * @throws InvalidAlgorithmParameterException
	 */
	public JSONObject decodeEncrData(String encrData, String v1, String sessionKey)
			throws InvalidAlgorithmParameterException {

		WXAESUtils aes = new WXAESUtils();
		byte[] resultByte = aes.decrypt(Base64.getDecoder().decode(encrData), Base64.getDecoder().decode(sessionKey),
				Base64.getDecoder().decode(v1));

		return JSONObject.parseObject(new String(WxPKCS7Encoder.decode(resultByte)));
	}


	/**
	 * 是否存在UNIONID 的用户
	 */
	@Override
	public Boolean existUnionId(String unionId) {
		return wxUserMapper.existUnionId(unionId) ;
	}
}
